﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using Nsf.Samples.RetryActivitySample.Client;
using Nsf.Samples.RetryActivitySample.Infrastructure.Actions;
using Nsf.Samples.RetryActivitySample.Infrastructure.Common.FaultDetails;
using Nsf.Samples.RetryActivitySample.Infrastructure.Utils;

namespace Nsf.Samples.RetryActivitySample.ServiceTest.Actions
{
    [Action(Name = "Retry workflow", Description = "Re-executes faulted activities of the selected workflow instance.")]
    public class RetryWorkflowAction : ActionBase
    {
        private const String WF_INSTANCE_ID = "InstanceId";

        protected override ICollection<string> GetKnownArguments()
        {
            var knownArguments = base.GetKnownArguments();
            knownArguments.Add(WF_INSTANCE_ID);
            return knownArguments;
        }

        protected override void ValidateArguments(IDictionary<String, String> args)
        {
            String instanceId;
            if (!args.TryGetValue(WF_INSTANCE_ID, out instanceId))
                throw new ValidationException("Argument '{0}' doesn't specified.", WF_INSTANCE_ID);
            if (instanceId.Count() == 0)
                throw new ValidationException("Value of the '{0}' doesn't specified.", WF_INSTANCE_ID);
            var res = instanceId.ToGuid();
            if (res == Guid.Empty)
                throw new ValidationException("'{0}' is invalid uuid.", instanceId);
            using (var client = new WorkflowManagerClient())
            {
                try
                {
                    client.GetRetryableWorkflow(res);
                }
                catch(FaultException<ProcessingFaultDetails> ex)
                {
                    throw new ValidationException("Can't load workflow with InstanceId = '{0}'{1}{2}.", instanceId, Environment.NewLine, ex.Detail);
                }
            }
        }

        protected override void OnExecute(IDictionary<String, String> args)
        {
            using (var client = new WorkflowManagerClient())
            {
                var workflowInstanceId = args[WF_INSTANCE_ID].ToGuid();
                var retryableWorkflow = client.GetRetryableWorkflow(workflowInstanceId);
                client.RetryWorkflow(retryableWorkflow);
                Console.WriteLine("'Retry' command was sended to workflow.");
            }
        }

        protected override void OnHelp()
        {
            throw new NotImplementedException();
        }
    }
}
